﻿
using System;
using System.Collections.Generic;
using Systemathics.FrameWork.Interfaces;

namespace Systemathics.FrameWork
{
    public sealed class DataService : IDisposable
    {
        public IDataProvider DataProvider{ get; private set;}
        private readonly Dictionary<Guid, int> SuscriptionCount;

        public event EventHandler<BarSeries>                    EmitBarSeries;
        public event EventHandler<TradeSeries>                  EmitTradeSeries;
        public event EventHandler<QuoteSeries>                  EmitQuoteSeries;
        public event EventHandler<Trade>                        EmitNewTrade;
        public event EventHandler<Blotter>                      EmitNewBlotter; 
        public event EventHandler<MarketData>                   EmitNewMarketData;

        public event EventHandler<FireMessageEventArgs>         EmitError;
        public event EventHandler<FireMessageEventArgs>         EmitConnectionStatus;

        public DataService(IDataProvider Dataprovider)
        {
            DataProvider = Dataprovider;
            SuscriptionCount = new Dictionary<Guid, int>();

            DataProvider.EmitNewBlotter += DataProviderEmitNewBlotter;
            DataProvider.EmitNewMarketData += DataProviderEmitNewMarketData;
            DataProvider.EmitNewTrade += DataProviderEmitNewTrade;

            DataProvider.EmitBarSeries += DataProviderEmitBarSeries;
            DataProvider.EmitQuoteSeries += DataProviderEmitQuoteSeries;
            DataProvider.EmitTradeSeries += DataProviderEmitTradeSeries;

            DataProvider.EmitError += DataProviderEmitError;
            DataProvider.EmitConnectionStatus += DataProviderEmitConnectionStatus;
        }

        private void DataProviderEmitConnectionStatus(object sender, FireMessageEventArgs e)
        {
            if (EmitConnectionStatus != null)
                EmitConnectionStatus(sender, e);
        }
        private void DataProviderEmitError(object sender, FireMessageEventArgs e)
        {
            if (EmitError != null)
                EmitError(sender, e);
        }
        private void DataProviderEmitTradeSeries(object sender, TradeSeries e)
        {
            if (EmitTradeSeries != null)
                EmitTradeSeries(sender, e);
        }
        private void DataProviderEmitQuoteSeries(object sender, QuoteSeries e)
        {
            if (EmitQuoteSeries != null)
                EmitQuoteSeries(sender, e);
        }
        private void DataProviderEmitNewTrade(object sender, Trade e)
        {
            if (EmitNewTrade != null)
                EmitNewTrade(sender, e);
        }
        private void DataProviderEmitNewMarketData(object sender, MarketData e)
        {
            if (EmitNewMarketData != null)
                EmitNewMarketData(sender, e);
        }
        private void DataProviderEmitNewBlotter(object sender, Blotter e)
        {
            if (EmitNewBlotter != null)
                EmitNewBlotter(sender, e);
        }
        private void DataProviderEmitBarSeries(object sender, BarSeries e)
        {
            if (EmitBarSeries != null)
                EmitBarSeries(sender, e);
        }

        #region IDataProvider Members

        public void GetHistoricalData(DateTime Begin, DateTime End, Data dt, Guid Id, int? BarSize)
        {
            DataProvider.GetHistoricalData(Begin, End, dt, Id, BarSize);
        }
        public void UpdateInstruments()
        {
            DataProvider.UpdateInstruments();
        }
        public void UpdateCurrencies()
        {
            DataProvider.UpdateCurrencies();
        }

        #endregion

        #region IConnection Members

        public string Name
        {
            get { return DataProvider.Name; }
        }
        public bool isConnected
        {
            get { return DataProvider.isConnected; }
        }
        public void Connect()
        {
           DataProvider.Connect();
        }
        public void Disconnect()
        {
            DataProvider.Disconnect();
        }
        public void Suscribe(Instrument instrument)
        {
            DataProvider.Suscribe(instrument);

            if (!SuscriptionCount.ContainsKey(instrument.Id))
                SuscriptionCount.Add(instrument.Id, 0);

            SuscriptionCount[instrument.Id]++;
        }
        public void Unsubscribe(Instrument instrument)
        {
            if (SuscriptionCount[instrument.Id] == 1)
                DataProvider.Unsubscribe(instrument);

            SuscriptionCount[instrument.Id]--;
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            DataProvider.EmitNewBlotter -= DataProviderEmitNewBlotter;
            DataProvider.EmitNewMarketData -= DataProviderEmitNewMarketData;
            DataProvider.EmitNewTrade -= DataProviderEmitNewTrade;

            DataProvider.EmitBarSeries -= DataProviderEmitBarSeries;
            DataProvider.EmitQuoteSeries -= DataProviderEmitQuoteSeries;
            DataProvider.EmitTradeSeries -= DataProviderEmitTradeSeries;
        }

        #endregion
    }
}
